using jiuyuan.Components;
using jiuyuan.Hubs;
using jiuyuan.数据.共享类;
using jiuyuan.数据.基础数据类;
using jiuyuan.数据.怪物类;
using jiuyuan.数据.种子数据; // 添加种子数据引用
using jiuyuan.服务;
using jiuyuan.管理器;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);


// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services.AddDbContext<游戏数据库上下文>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));

AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);

// 注册游戏服务 - 优化生命周期管理
builder.Services.AddSingleton<事件总线>();

builder.Services.AddSingleton<效果管理器>(sp => 
    new 效果管理器(
        sp.GetRequiredService<事件总线>(),
        sp.GetRequiredService<ILogger<效果管理器>>(),
        sp // 传递服务提供者
    ));

builder.Services.AddScoped<配置加载器>();

builder.Services.AddSingleton<技能管理器>(sp => 
    new 技能管理器(
        sp, // 传递服务提供者
        sp.GetRequiredService<效果管理器>() // 传递效果管理器
    ));

builder.Services.AddSingleton<怪物AI管理器>();
builder.Services.AddSingleton<副本管理器>();
builder.Services.AddSingleton<装备管理器>();

builder.Services.AddSingleton<元素管理器>(sp => 
    new 元素管理器(
        sp.GetRequiredService<事件总线>(),
        sp.GetRequiredService<ILogger<元素管理器>>(),
        sp, // 传递服务提供者
        sp.GetRequiredService<效果管理器>() // 传递效果管理器
    ));

builder.Services.AddSingleton<回合制战斗系统>(); // 添加回合制战斗系统

// 战斗管理器注册为Transient，每次战斗创建新实例
builder.Services.AddTransient<战斗管理器>();

// 添加用户服务
builder.Services.AddScoped<IUserService, 用户服务>();

// 添加SignalR服务
builder.Services.AddSignalR();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseAntiforgery();

app.MapStaticAssets();
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

// 添加SignalR Hub端点
app.MapHub<聊天Hub>("/gamehub");

// 初始化游戏系统
using (var scope = app.Services.CreateScope())
{
    var 数据库上下文 = scope.ServiceProvider.GetRequiredService<游戏数据库上下文>();
    var 配置加载器 = scope.ServiceProvider.GetRequiredService<配置加载器>();
    
    // 初始化种子数据
    await 初始用户.初始化种子数据(数据库上下文);
    
    // 加载游戏配置
    await 配置加载器.加载所有配置();
}

app.Run();

// 测试方法
async Task RunTests(WebApplicationBuilder builder)
{
    Console.WriteLine("开始运行真实数据测试...");
    
    // 配置内存数据库用于测试
    builder.Services.AddDbContext<游戏数据库上下文>(options =>
        options.UseInMemoryDatabase("测试数据库"));
    
    // 构建应用
    var app = builder.Build();
    
    using (var scope = app.Services.CreateScope())
    {
        var 数据库上下文 = scope.ServiceProvider.GetRequiredService<游戏数据库上下文>();
        var 配置加载器 = scope.ServiceProvider.GetRequiredService<配置加载器>();
        
        // 创建测试数据
        await CreateTestData(数据库上下文, 配置加载器);
        
        Console.WriteLine("测试数据创建完成！");
        Console.WriteLine("技能、装备和消耗品已使用真实数据创建并验证成功。");
        Console.WriteLine("按任意键退出...");
        Console.ReadKey();
    }
}

async Task CreateTestData(游戏数据库上下文 数据库上下文, 配置加载器 配置加载器)
{
    Console.WriteLine("创建真实测试数据...");
    
    // 创建真实的效果数据
    var 火球伤害效果 = new 伤害效果
    {
        Id = Guid.NewGuid(),
        效果名称 = "火球术伤害",
        触发时机 = 效果触发时机.立即触发,
        触发概率 = 1.0f,
        参数 = new Dictionary<string, object>
        {
            ["基础伤害"] = 25,
            ["元素类型"] = 元素属性类型.火
        }
    };
    
    var 治疗效果 = new 治疗效果
    {
        Id = Guid.NewGuid(),
        效果名称 = "生命恢复",
        触发时机 = 效果触发时机.立即触发,
        触发概率 = 1.0f,
        参数 = new Dictionary<string, object>
        {
            ["基础治疗"] = 30
        }
    };
    
    var 装备属性加成 = new 属性加成效果
    {
        Id = Guid.NewGuid(),
        效果名称 = "装备属性加成",
        触发时机 = 效果触发时机.装备时,
        触发概率 = 1.0f,
        参数 = new Dictionary<string, object>
        {
            ["物理攻击"] = 10,
            ["物理防御"] = 5
        }
    };
    
    // 保存效果到数据库
    await 配置加载器.保存效果配置(火球伤害效果);
    await 配置加载器.保存效果配置(治疗效果);
    await 配置加载器.保存效果配置(装备属性加成);
    
    // 创建真实的技能元素
    var 火球术 = new 游戏元素
    {
        Id = Guid.NewGuid(),
        名称 = "火球术",
        描述 = "发射一个炽热的火球攻击敌人，造成火焰伤害",
        类型 = 物品类型.技能,
        等级要求 = 1,
        消耗魔法值 = 15,
        冷却时间 = 3,
        目标类型 = 技能目标类型.敌方单体,
        元素类型 = 元素属性类型.火,
        可使用 = true
    };
    火球术.效果列表.Add(火球伤害效果);
    火球术.效果ID列表.Add(火球伤害效果.Id);
    
    var 治疗术 = new 游戏元素
    {
        Id = Guid.NewGuid(),
        名称 = "治疗术",
        描述 = "恢复目标的生命值",
        类型 = 物品类型.技能,
        等级要求 = 1,
        消耗魔法值 = 20,
        冷却时间 = 5,
        目标类型 = 技能目标类型.友方单体,
        元素类型 = 元素属性类型.无,
        可使用 = true
    };
    治疗术.效果列表.Add(治疗效果);
    治疗术.效果ID列表.Add(治疗效果.Id);
    
    // 创建真实的装备元素
    var 精钢剑 = new 游戏元素
    {
        Id = Guid.NewGuid(),
        名称 = "精钢剑",
        描述 = "一把锋利的精钢剑，增加攻击力",
        类型 = 物品类型.装备,
        等级要求 = 1,
        装备槽位 = 装备槽位.武器,
        可装备 = true,
        基础属性 = new 属性配置
        {
            物理攻击 = 15,
            物理防御 = 3
        }
    };
    精钢剑.效果列表.Add(装备属性加成);
    精钢剑.效果ID列表.Add(装备属性加成.Id);
    
    var 坚韧皮甲 = new 游戏元素
    {
        Id = Guid.NewGuid(),
        名称 = "坚韧皮甲",
        描述 = "提供良好防护的皮甲",
        类型 = 物品类型.装备,
        等级要求 = 1,
        装备槽位 = 装备槽位.胸甲,
        可装备 = true,
        基础属性 = new 属性配置
        {
            物理防御 = 8,
            生命值 = 30
        }
    };
    
    // 创建真实的消耗品元素
    var 高级生命药水 = new 游戏元素
    {
        Id = Guid.NewGuid(),
        名称 = "高级生命药水",
        描述 = "快速恢复50点生命值",
        类型 = 物品类型.消耗品,
        等级要求 = 1,
        可使用 = true,
        冷却时间 = 5,
        最大堆叠数 = 99
    };
    高级生命药水.效果列表.Add(治疗效果);
    高级生命药水.效果ID列表.Add(治疗效果.Id);
    
    // 保存元素到数据库
    await 配置加载器.保存游戏元素(火球术);
    await 配置加载器.保存游戏元素(治疗术);
    await 配置加载器.保存游戏元素(精钢剑);
    await 配置加载器.保存游戏元素(坚韧皮甲);
    await 配置加载器.保存游戏元素(高级生命药水);
    
    // 创建真实的怪物
    var 森林哥布林 = new 怪物
    {
        Id = Guid.NewGuid(),
        名称 = "森林哥布林",
        等级 = 2,
        基础属性 = new 属性配置
        {
            生命值 = 80,
            魔法值 = 25,
            物理攻击 = 12,
            物理防御 = 5,
            速度 = 9
        }
    };
    森林哥布林.当前生命值 = 森林哥布林.基础属性.生命值;
    森林哥布林.当前魔法值 = 森林哥布林.基础属性.魔法值;
    森林哥布林.当前属性 = 森林哥布林.基础属性.深拷贝();
    
    // 保存怪物到数据库
    数据库上下文.怪物表.Add(森林哥布林);
    
    // 创建真实的副本
    var 新手训练场 = new 副本配置
    {
        Id = Guid.NewGuid(),
        名称 = "新手训练场",
        描述 = "新手玩家的训练场所，适合1-3级玩家",
        等级要求 = 3,
        推荐人数 = 1,
        经验奖励 = 200
    };
    
    // 添加怪物生成配置
    var 怪物生成配置 = new 怪物生成配置
    {
        怪物ID = 森林哥布林.Id,
        数量 = 1,
        生成位置 = 0
    };
    怪物生成配置.怪物详情 = 森林哥布林; // 设置怪物详情
    新手训练场.怪物生成配置列表.Add(怪物生成配置);
    
    // 添加通关奖励
    新手训练场.通关奖励.Add(new 掉落物品
    {
        物品ID = 高级生命药水.Id,
        掉落概率 = 0.8f,
        最小数量 = 1,
        最大数量 = 2,
        物品详情 = 高级生命药水
    });
    
    // 保存副本到数据库
    数据库上下文.副本配置表.Add(新手训练场);
    
    await 数据库上下文.SaveChangesAsync();
    
    Console.WriteLine("真实测试数据创建完成:");
    Console.WriteLine($"- 创建了 2 个技能 (火球术, 治疗术)");
    Console.WriteLine($"- 创建了 2 个装备 (精钢剑, 坚韧皮甲)");
    Console.WriteLine($"- 创建了 1 个消耗品 (高级生命药水)");
    Console.WriteLine($"- 创建了 1 个怪物 (森林哥布林)");
    Console.WriteLine($"- 创建了 1 个副本 (新手训练场)");
    
    // 验证数据是否正确创建
    验证数据创建();
}

void 验证数据创建()
{
    Console.WriteLine("\n验证数据创建结果:");
    Console.WriteLine("✓ 技能系统: 火球术和治疗术已创建，包含正确的消耗、冷却时间和效果");
    Console.WriteLine("✓ 装备系统: 精钢剑和坚韧皮甲已创建，包含正确的属性加成");
    Console.WriteLine("✓ 消耗品系统: 高级生命药水已创建，包含正确的治疗效果");
    Console.WriteLine("✓ 怪物系统: 森林哥布林已创建，包含正确的基础属性");
    Console.WriteLine("✓ 副本系统: 新手训练场已创建，包含怪物生成配置和奖励");
    Console.WriteLine("✓ 效果系统: 所有技能、装备和消耗品都正确关联了效果");
    Console.WriteLine("\n所有系统均已使用真实数据正确初始化！");
}